if ( SERVER ) then
	
	GM.Spawngroups = {}
	Default( "RespawnTime", 5 )
	Default( "AddRespawnTime", 5 )

	function GM:FindSpawnGroups()
		self.Spawngroups = ents.FindByClass( "inc_spawngroup" )
	end
	GM:AddHook( "InitPostEntity", "FindSpawnGroups" )
	
	function GM:SetRespawnTime( ply )
		if ( self:IsFight() ) then
			local total, alive, dead = self:GeneratorStats()
			ply.RespawnTime = CurTime() + self.RespawnTime + self.AddRespawnTime * dead
		else
			ply.RespawnTime = CurTime() + 2
			--return
		end
		
		umsg.Start( "SetRespawnTime", ply )
			umsg.Short( ply.RespawnTime - CurTime() )
		umsg.End()
	end
	GM:AddHook( "PlayerDeath", "SetRespawnTime" )

	function GM:PlayerDeathThink() end
	
	function GM:CheckRespawnTime( ply )
		if not ply.spawngroup then self:SelectFirstSpawngroup (ply) end
		if ( CurTime() > ( ply.RespawnTime or 0 ) ) then
			if not ply.gotSpawnSelect then
				umsg.Start( "SpawnSelect", ply )
				umsg.End()
				ply.gotSpawnSelect = true
				if not ply.spawngroup.Enabled then
					ply.spawngroup = self:SelectNextLegalSpawngroup (ply)
				end
				printd ("spawngroup",ply.spawngroup)
				ply:SetViewEntity (ply.spawngroup)
			elseif ply:KeyPressed( IN_ATTACK2 ) then
				ply.spawngroup = self:SelectNextLegalSpawngroup (ply)
				printd ("spawngroup",ply.spawngroup)
				ply:SetViewEntity (ply.spawngroup)
				umsg.Start( "SpawnSelectViewChange", ply )
				umsg.End()
			elseif ply:KeyPressed( IN_ATTACK ) then
				ply:Spawn()
				ply.gotSpawnSelect = false
				ply:SetViewEntity (ply)
			end
		end
	end
	GM:AddHook( "PlayerDeathThink", "CheckRespawnTime" )
	
	function GM:PlayerSelectSpawn( ply )
		if not ply.spawngroup then self:SelectFirstSpawngroup (ply) end
		local spawngroup = ply.spawngroup
		printd (spawngroup)
		if not spawngroup or not spawngroup.Enabled then
			ply.spawngroup = self:SelectNextLegalSpawngroup (ply)
			spawngroup = ply.spawngroup
		end

		if !spawngroup then
			return self.BaseClass:PlayerSelectSpawn(ply)
		end
		
		local points = spawngroup:GetSpawnPoints()
		for i=1, 10 do
			local ran = math.random(1, #points)
			local spawn = points[ ran ]
			if IsValid (spawn) then
				printd ("spawn", spawn, "\n")
				return spawn
			else
				table.remove( points, ran )
			end
		end
		return spawngroup --this is stupid. Heh. Meh.
	end
	
	function GM:SelectFirstSpawngroup (ply)
		ply.spawngroup = self.Spawngroups[1]
	end
	
	function GM:SelectNextLegalSpawngroup (ply)
		PrintTable (self.Spawngroups)
		for k,v in pairs (self.Spawngroups) do
			printd ("spawngroup", v:EntIndex(), "player's spawngroup", ply.spawngroup:EntIndex())
			if (v:EntIndex() > ply.spawngroup:EntIndex()) and v.Enabled then
				return v
			end
		end
		--if we get this far, try again
		printd ("failed finishing table")
		for k,v in pairs (self.Spawngroups) do
			if v.Enabled then
				return v
			end
		end
		--otherwise, we give up
		printd ("no legal spawngroups, defaulting")
		return self.Spawngroups[1]
	end
	
end
if ( CLIENT ) then
	--camera control stuff
	local override_angles = Angle (0,0,0)
	local sensitivity = 0.05
	
	local SFTR30 = Font( "SF TransRobotics", ScrW() / 40 )
	local totalLength, nextSpawn, nextSpawnRecvTime = 0, 0, 0
	function GM:DrawRespawnTime()
		--if ( self:IsBuild() ) then return end
		if ( LocalPlayer():Alive() ) then
			spawnSelecting = false
			override_angles = Angle (0,0,0)
			return
		end
		
		local timeLeft = nextSpawn - CurTime()
		local percent = math.Clamp( (CurTime() - nextSpawnRecvTime) / 2, 0, 1 )
		local alpha = 255 * percent
		
		if ( alpha == 0 ) then return end
		surface.SetDrawColor( 0, 0, 0, math.min( alpha * 1.5, 255 ) )
		surface.DrawRect( 0, 0, ScrW(), ScrH() * 0.15 )
		surface.DrawRect( 0, ScrH() * 0.85, ScrW(), ScrH() )
		
		local text = ""
		if ( timeLeft > 0 ) then
			text = "Respawning in: " .. math.ceil( timeLeft )
		else
			text = "Primary fire key: respawn.        Secondary fire key: cycle spawn areas"
		end
		
		draw.SimpleText(
			text, SFTR30,
			ScrW() / 2, ScrH() * 0.9,
			Color( 255, 255, 255, alpha ),
			TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER
		)
		
		if timeLeft < 0 then
			draw.SimpleText(
				"Hold Jump key to control camera angle", SFTR30,
				ScrW() / 2, ScrH() * 0.95,
				Color( 255, 255, 255, alpha ),
				TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER
			)
		end
	end
	GM:AddHook( "HUDPaint", "DrawRespawnTime" )
	
	function GM.ReceiveRespawnTime( msg )
		totalLength = msg:ReadShort()
		nextSpawn = CurTime() + totalLength
		nextSpawnRecvTime = CurTime()
	end
	usermessage.Hook( "SetRespawnTime", GM.ReceiveRespawnTime )
	
	function GM.ReceiveSpawnSelect( msg )
		spawnSelecting = true
	end
	usermessage.Hook( "SpawnSelect", GM.ReceiveSpawnSelect )
	
	function GM.ReceiveSpawnSelectViewChange( msg )
		override_angles = Angle (0,0,0)
	end
	usermessage.Hook( "SpawnSelectViewChange", GM.ReceiveSpawnSelectViewChange )
	
	function GM:NoRedTint( name )
		--if ( self:IsBuild() ) then return end
		local ply = LocalPlayer()
		if ( !IsValid( ply ) || ply:Alive() ) then return end
		if ( name == "CHudDamageIndicator" ) then return false end
	end
	GM:AddHook( "HUDShouldDraw", "NoRedTint" )
	
	function GM:RespawnScreenCameraControl(cmd, x, y, ang)
		if !spawnSelecting then return end
		local ply = LocalPlayer()
		if !IsValid(ply) then return end

		if ply:KeyDown (IN_JUMP) then
			override_angles.y = override_angles.y - x * sensitivity
			override_angles.p = override_angles.p + y * sensitivity
		end
	end
	GM:AddHook("InputMouseApply", "RespawnScreenCameraControl")

	function GM:RespawnScreenCameraView (ply, origin, angles, fov)
		if !spawnSelecting then return end

		if !ply:KeyDown(IN_JUMP) then
			if override_angles.y > 180 then override_angles.y = override_angles.y - 360 end
			if override_angles.y < -180 then override_angles.y = override_angles.y + 360 end
			override_angles.y = override_angles.y / (1 + FrameTime())
			override_angles.p = override_angles.p / (1 + FrameTime())
		end
		
		--printd (origin, angles) 
		return {angles = angles + override_angles}
	end
	GM:AddHook ("CalcView", "RespawnScreenCameraView")
	
end
